package model.soldering;

import java.util.ArrayList;
import java.util.List;

import model.IManufacturingMethod;
import model.ManufacturingMethod;
import model.auxillary.Parameter;
import model.auxillary.ParameterCollection;
import model.auxillary.ParameterList;
import model.auxillary.ParameterList.ParameterType;

/**
 * The class {@code SolderPastePrinting} models the process step in which 
 * the soldering paste is printed on the circuit board.
 * @author Sebastian Perlwitz
 *
 */
public class SolderPastePrinting extends ManufacturingMethod implements
	IManufacturingMethod{
	
	/**
	 * To create a new instance of a {@code SolderPastePrinting} process.
	 * @param name the name of the process.	 
	 */
	public SolderPastePrinting(String name) {
		super(name, "Lotpastenauftrag" + getManuMethodsCreatedCount());
		subType = SubType.SOLDER_PASTE_PRINTING;
		super.addParameters();
		addParameters();
	}
	
	@Override
	protected void addParameters() {
		List<Parameter> newParams = new ArrayList<Parameter>();
		
		newParams.add(new Parameter(
				"Masse der Leiterplatte",
				"mass_circuitBoard",
				"<html>m<sub>LP</sub></html>",
				"<html>[kg]</html>",
				true,
				this));
		
		newParams.add(new Parameter(
				"Masse Rakel",
				"massSqueegee",
				"<html>m<sub>R</sub></html>",
				"<html>[kg]</html>",
				true,
				this));
		
		newParams.add(new Parameter(
				"Masse Transportband",
				"massConveyor",
				"<html>m<sub>T</sub></html>",
				"<html>[kg]</html>",
				true,
				this));
		
		newParams.add(new Parameter(
				"Masse Werkzeug",
				"massTool",
				"<html>m<sub>WZ</sub></html>",
				"<html>[kg]</html>",
				true,
				this));
		
		newParams.add(new Parameter(
				"Lotpastenmasse",
				"massSolderPaste",
				"<html>m<sub>Lotpaste</sub></html>",
				"<html>[kg]</html>",
				true,
				this));
		
		newParams.add(new Parameter(
				"Reibungskoeffizient zwischen Rakel und Schablone",
				"muFriction1",
				"<html>&mu;<sub>G</sub></html>",
				"<html>[1]</html>",
				true,
				this));
		
		newParams.add(new Parameter(
				"Reibungskoeffizient an Werkzeug bei horizontaler Bewegung",
				"muFriction2",
				"<html>&mu;<sub>G</sub></html>",
				"<html>[1]</html>",
				true,
				this));
		
		newParams.add(new Parameter(
				"Reibungskoeffizient zwischen Rakel und Werkzeug",
				"muFriction3",
				"<html>&mu;<sub>G</sub></html>",
				"<html>[1]</html>",
				true,
				this));
		
		parameters.addParameters(ParameterType.MATERIAL_PARAMETER, newParams);
		newParams.clear();
		
		newParams.add(new Parameter(
				"Bewegung Leiterplatte in vertikaler Richtung",
				"delta_z_LP",
				"<html>&Delta;z<sub>LP</sub></html>",
				"<html>[mm]</html>",
				true,
				this));
		
		newParams.add(new Parameter(
				"Bewegung Rakel in vertikaler Richtung",
				"delta_z_R",
				"<html>&Delta;z<sub>R</sub></html>",
				"<html>[mm]</html>",
				true,
				this));
		
		newParams.add(new Parameter(
				"Anpresskraft",
				"F_A",
				"<html>F<sub>A</sub></html>",
				"<html>[N]</html>",
				true,
				this));
		
		newParams.add(new Parameter(
				"Wegstrecke",
				"length",
				"<html>l<sub>W</sub></html>",
				"<html>[mm]</html>",
				true,
				this));
		
		newParams.add(new Parameter(
				"Vertikale Geschwindigkeit Rakel",
				"vSqueegeeVertical",
				"<html>v<sub>R,z</sub></html>",
				"<html>[m/s]</html>",
				true,
				this));
		
		newParams.add(new Parameter(
				"Horizontale Geschwindigkeit Rakel",
				"vSqueegeeHorizontal",
				"<html>v<sub>R,x</sub></html>",
				"<html>[m/s]</html>",
				true,
				this));
		
		parameters.addParameters(ParameterType.GEOMETRY_PARAMETER, newParams);
	}

	@Override
	public void calculate() {
		
		aborted = false;
		error = false;
		
		//Calculation of physical energy minimum
		double mass_circuitBoard = getParameter("mass_circuitBoard",
				ParameterType.MATERIAL_PARAMETER).getValue();
		double delta_z_LP = getParameter("delta_z_LP",
				ParameterType.GEOMETRY_PARAMETER).getValue();
		
		double eMinPhy = (mass_circuitBoard * 9.81 * 
				(delta_z_LP / 1000)) / 3600; //[Wh]
		System.out.println("eMinPhy: " + eMinPhy);
		
		//Calculation of technological energy minimum
		double massSqueegee = getParameter("massSqueegee",
				ParameterType.MATERIAL_PARAMETER).getValue();
		double delta_z_R = getParameter("delta_z_R",
				ParameterType.GEOMETRY_PARAMETER).getValue();
		double massConveyor = getParameter("massConveyor",
				ParameterType.MATERIAL_PARAMETER).getValue();
		double vSqueegeeVertical = getParameter("vSqueegeeVertical",
				ParameterType.GEOMETRY_PARAMETER).getValue();
		double vSqueegeeHorizontal = getParameter("vSqueegeeHorizontal",
				ParameterType.GEOMETRY_PARAMETER).getValue();
		double massTool = getParameter("massTool",
				ParameterType.MATERIAL_PARAMETER).getValue();
		double massSolderPaste = getParameter("massSolderPaste",
				ParameterType.MATERIAL_PARAMETER).getValue();
		double f_A = getParameter("F_A",
				ParameterType.GEOMETRY_PARAMETER).getValue();
		double muFriction1 = getParameter("muFriction1",
				ParameterType.MATERIAL_PARAMETER).getValue();
		double muFriction2 = getParameter("muFriction2",
				ParameterType.MATERIAL_PARAMETER).getValue();
		double muFriction3 = getParameter("muFriction3",
				ParameterType.MATERIAL_PARAMETER).getValue();
		double length = getParameter("length",
				ParameterType.GEOMETRY_PARAMETER).getValue();
		
		double ePotSqueegee = (massSqueegee * 9.81 * delta_z_R/1000) / 3600; //[Wh]
		System.out.println("ePotSqueegee: " + ePotSqueegee);
		double ePotConveyor = (massConveyor * 9.81 * delta_z_LP/1000) / 3600; //[Wh]
		System.out.println("ePotConveyor: " + ePotConveyor);
		double ePot = ePotSqueegee + ePotConveyor;
		System.out.println("ePot: " + ePot);
		
		double eKin1 = (0.5 * massSqueegee * 
				vSqueegeeVertical * vSqueegeeVertical) / 3600; //[Wh]
		System.out.println("eKin1: " + eKin1);
		double eKin2 = (0.5 * (massTool + massSolderPaste) * 
				vSqueegeeHorizontal * vSqueegeeHorizontal) / 3600; //[Wh]
		System.out.println("eKin2: " + eKin2);
		double eKin = eKin1 + eKin2;
		System.out.println("eKin: " + eKin);
		
		double eFric1 = (muFriction1 * f_A * length/1000) / 3600; //[Wh]
		System.out.println("eFric1: " + eFric1);
		double eFric2 = (muFriction2 * (massSolderPaste + massTool) * 
				9.81 * length/1000) / 3600; //[Wh]
		System.out.println("eFric2: " + eFric2);
		double eFric3 = (muFriction3 * massSqueegee * 9.81 * 
				delta_z_R/1000) / 3600; //[Wh]
		System.out.println("eFric3: " + eFric3);
		double eFric = eFric1 + eFric2 + eFric3;
		System.out.println("eFric: " + eFric);
		
		double eMinTech = eMinPhy + ePot + eKin + eFric;
		System.out.println("eMinTech: " + eMinTech);
		
		//Calculation of real energy minimum
		double eta_ges = getParameter("eta_ges",
				ParameterType.PROCESS_PARAMETER).getValue();
		
		double eMinReal = eMinTech + (((1 / eta_ges) - 1) * eMinTech);
		System.out.println("eMinReal: " + eMinReal);
		
		//Setting the results of the overall process
    	double eAct = getParameter("E_ist",
				ParameterType.PROCESS_PARAMETER).getValue();
    	
    	getParameter("E_min,phy",
				ParameterType.RESULT_PARAMETER).setValue(eMinPhy);
    	getParameter("E_min,tech",
				ParameterType.RESULT_PARAMETER).setValue(eMinTech);
    	getParameter("E_min,real",
				ParameterType.RESULT_PARAMETER).setValue(eMinReal);
    	
    	setPhysicalEffectiveness(eAct, eMinPhy);
    	setTechnologicalEffectiveness(eAct, eMinTech);
    	setRealEffectiveness(eAct, eMinReal);
		
		if(error || aborted) {
            calculated = false;
        } else {
            calculated = true;
        }
	}
	
	@Override
	public ParameterType[] getInputParameterTypes() {
		ParameterType[] result = new ParameterType[3];
		result[0] = ParameterType.PROCESS_PARAMETER;
		result[1] = ParameterType.MATERIAL_PARAMETER;
		result[2] = ParameterType.GEOMETRY_PARAMETER;
		return result;
	}

	@Override
	public ParameterList addPartProcess() throws IndexOutOfBoundsException {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public ParameterCollection addTool() {
		// TODO Auto-generated method stub
		return null;
	}

}
